package info.ericbutler.microcosm.game;

import info.ericbutler.microcosm.entities.Player;
import info.ericbutler.microcosm.entities.UpdatingGameElement;
import info.ericbutler.microcosm.enums.AnimationName;
import info.ericbutler.microcosm.world.GameSquare;
import info.ericbutler.microcosm.world.Microcosm;

import java.util.Vector;

import org.newdawn.slick.Animation;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class SinglePlayerState extends BasicGameState {
	private int							id;
	private int							blinkTime	= 8500;
	public static Player				player;
	private Microcosm					world;
	private Vector<UpdatingGameElement>	postDraw	= new Vector<UpdatingGameElement>();

	public SinglePlayerState(int SINGLE_PLAYER_STATE) {
		this.id = SINGLE_PLAYER_STATE;
	}

	@Override
	public void init(GameContainer container, StateBasedGame game) throws SlickException {
		world = new Microcosm();
		player = new Player( new Vector2f( 100, 100 ) );
		player.setCurrentWorld( world );
		player.addAnimation( AnimationName.MOVE_SOUTH, new Animation( new SpriteSheet( "rsc/images/sprites/crono_walking_south_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.MOVE_NORTH, new Animation( new SpriteSheet( "rsc/images/sprites/crono_walking_north_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.MOVE_EAST, new Animation( new SpriteSheet( "rsc/images/sprites/crono_walking_east_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.MOVE_WEST, new Animation( new SpriteSheet( "rsc/images/sprites/crono_walking_west_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.IDLE_SOUTH, new Animation( new SpriteSheet( "rsc/images/sprites/crono_idle_south_60x60.png", 60, 60 ), 150 ) );
		player.getAnimation( AnimationName.IDLE_SOUTH ).setDuration( 0, blinkTime );
		player.addAnimation( AnimationName.IDLE_NORTH, new Animation( new SpriteSheet( "rsc/images/sprites/crono_idle_north_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.IDLE_EAST, new Animation( new SpriteSheet( "rsc/images/sprites/crono_idle_east_60x60.png", 60, 60 ), 150 ) );
		player.getAnimation( AnimationName.IDLE_EAST ).setDuration( 0, blinkTime );
		player.addAnimation( AnimationName.IDLE_WEST, new Animation( new SpriteSheet( "rsc/images/sprites/crono_idle_west_60x60.png", 60, 60 ), 150 ) );
		player.getAnimation( AnimationName.IDLE_WEST ).setDuration( 0, blinkTime );
		player.addAnimation( AnimationName.ATTACK_SOUTH, new Animation( new SpriteSheet( "rsc/images/sprites/crono_swinging_south_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.ATTACK_NORTH, new Animation( new SpriteSheet( "rsc/images/sprites/crono_swinging_north_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.ATTACK_EAST, new Animation( new SpriteSheet( "rsc/images/sprites/crono_swinging_east_60x60.png", 60, 60 ), 150 ) );
		player.addAnimation( AnimationName.ATTACK_WEST, new Animation( new SpriteSheet( "rsc/images/sprites/crono_swinging_west_60x60.png", 60, 60 ), 150 ) );
	}

	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
		for( int depth = 0; depth < 1; depth++ ) {
			for( int row = 0; row < 48; row++ ) {
				for( int col = 0; col < 64; col++ ) {
					world.getTiles()[row][col][depth].render( container, game, g );
					if( new Rectangle( col * Microcosm.TILE_SCALE_PIXELS, row * Microcosm.TILE_SCALE_PIXELS, world.getTiles()[row][col][depth].getAnimation().getWidth(),
							world.getTiles()[row][col][depth].getAnimation().getHeight() ).intersects( player.getCollisionBox() ) ) {
						// Basically, if this is the last square yplayer is occupying (checking for his lower right corner) then draw him
						if( player.getCollisionBox().getMaxY() <= ( row + 1 ) * Microcosm.TILE_SCALE_PIXELS
								&& player.getCollisionBox().getMaxX() <= ( col + 1 ) * Microcosm.TILE_SCALE_PIXELS ) {
							player.render( container, game, g );
						}
					}
				}
			}
		}
		// Draw GUI
		if( player.isInventoryOpen() ) {
			player.getInventory().render( container, game, g );
		}
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
		controls( container, game, delta );
		player.update( container, game, delta );
		this.world.update( container, game, delta );
	}

	private void controls(GameContainer container, StateBasedGame game, int delta) {
		Input inputs = container.getInput();
		// Handle mouse clicks
		if( inputs.isMousePressed( Input.MOUSE_LEFT_BUTTON ) ) {
			if( player.getInventory().isDraggingInventory() ) {
				player.getInventory().setDraggingInventory( false );
			}
			if( player.isInventoryOpen() && player.getInventory().getUIBoundingBox().contains( inputs.getMouseX(), inputs.getMouseY() ) ) {
				player.getInventory().checkBoxClicks( inputs.getMouseX(), inputs.getMouseY() );
			} else {
				if( MicrocosmMain.MOUSE_ITEM != null && MicrocosmMain.MOUSE_ITEM.getItemType().isPlaceable() ) {
					// Find square they clicked
					GameSquare targetTile = this.world.getTile( inputs.getMouseX(), inputs.getMouseY() );
					// Replace terrain if it's OK to
					if( !MicrocosmMain.MOUSE_ITEM.getItemType().getWorldTile().equals( targetTile ) ) {
						player.getInventory().removeItem( MicrocosmMain.MOUSE_ITEM, 1 );
						this.world.setTile(
								targetTile.getCol(),
								targetTile.getRow(),
								targetTile.getDepth(),
								MicrocosmMain.MOUSE_ITEM.getItemType().getWorldTile().clone().setCol( targetTile.getCol() ).setRow( targetTile.getRow() )
										.setDepth( targetTile.getDepth() ).setMyWorld( targetTile.getMyWorld() ) );
						this.world.getTile( inputs.getMouseX(), inputs.getMouseY() ).update( container, game, delta );
						if( MicrocosmMain.MOUSE_ITEM.getStackSize() == 0 ) {
							MicrocosmMain.MOUSE_ITEM = null;
						}
					}
				}
			}
		} else if( inputs.isMousePressed( Input.MOUSE_RIGHT_BUTTON ) && MicrocosmMain.MOUSE_ITEM != null ) {
			MicrocosmMain.MOUSE_ITEM = null;
		}
	}

	@Override
	public int getID() {
		return id;
	}
}
